#include <iostream>
#include <thread>
#include <memory>
#include <mutex>
#include <atomic>
#include <condition_variable>

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <signal.h> // signal functions

using namespace std;
class Test
{
  public:
    Test()
    {
        work_thread_ = new std::thread(&Test::work_func, this);
    }
    ~Test()
    {
        printf("eixt0\n");
        if (work_thread_)
        {
            printf("eixt1\n");
            {
                std::unique_lock<std::mutex> lock(work_mutex_);
                flag_exit_ = true;
                work_flag_ = true;
                printf("eixt2\n");
                work_cv_.notify_one();
            }
            printf("eixt3\n");
            work_thread_->join();
            delete work_thread_;
        }
    }

    void notify()
    {
        std::unique_lock<std::mutex> lock(work_mutex_);
        work_flag_ = true;
        printf("notify\n");
        work_cv_.notify_one();
    }
    void work_func()
    {
        while (1)
        {
            {
                std::unique_lock<std::mutex> lck(work_mutex_);
                while (!work_flag_) work_cv_.wait(lck);
                if (flag_exit_)
                    break;
                work_flag_ = false;
            }
            sleep(5);
            printf("working ...\n");
        }
    }

  private:
    std::thread            *work_thread_; // slam工作线程
    std::atomic_bool        work_flag_;
    std::atomic_bool        flag_exit_;
    std::mutex              work_mutex_;
    std::condition_variable work_cv_;
};

volatile sig_atomic_t flag = 0;

static void my_handler(int sig)
{
    flag = 1; // set flag
    cout << "ctrl c" << endl;
}

int main(int argc, char const *argv[])
{
    cout << "start" << endl;

    // signal(SIGINT, my_handler);
    Test test;
    while (1)
        ;

    return 0;
}